<template>
  <a-spin :spinning="loading">
    <div class="modal-header">
      <div class="modal-title">
        {{ !!!id ? l('CreateNewUser') : l('Edit') }}
      </div>
    </div>
    <slot></slot>
    <div class="modal-body">
      <!-- tab切换 -->
      <a-tabs defaultActiveKey="1">
        <!-- 用户信息 -->
        <a-tab-pane key="1">
          <template #tab>
            <user-outlined />
            {{ l('UserInformations') }}
          </template>
          <a-form
            :rules="rules"
            :label-col="{ style: { width: '200px' } }"
            labelAlign="right"
            @submit="handleSubmit"
            ref="formRef"
            :model="form"
            layout="vertical"
          >
            <a-row>
              <a-col :span="12">
                <a-form-item :label="l('UploadProfilePicture')">
                  <a-upload
                    name="profilePictureFile"
                    :action="uploadPictureUrl"
                    listType="picture-card"
                    v-model:file-list="fileList"
                    :before-upload="beforeUpload"
                    accept="image/*"
                    :headers="uploadHeaders"
                    @preview="handlePreview"
                    @change="uploadPictureChange"
                  >
                    <div v-if="fileList.length < 1">
                      <div class="ant-upload-text">
                        <plus-outlined />
                        {{ l('UploadProfilePicture') }}
                      </div>
                    </div>
                  </a-upload>
                  <a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
                    <img alt="example" style="width: 100%" :src="previewImage" />
                  </a-modal>
                </a-form-item>
              </a-col>
            </a-row>
            <!-- 头像 -->

            <a-row>
              <a-col :span="12">
                <!-- 用户名 -->
                <a-form-item :label="l('UserName')" name="userName">
                  <a-input :placeholder="l('UserName')" v-model:value="form.userName" />
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <!-- 邮箱 -->
                <a-form-item :label="l('EmailAddress')" name="emailAddress">
                  <a-input :placeholder="l('EmailAddress')" v-model:value="form.emailAddress" />
                </a-form-item>
              </a-col>
            </a-row>
            <a-row>
              <a-col :span="12">
                <!-- 密码 -->
                <a-form-item :label="l('Password')" name="password" :rules="passwordRules">
                  <a-input
                    :placeholder="l('Password')"
                    type="password"
                    v-model:value="form.password"
                  />
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <!-- 电话号码 -->
                <a-form-item :label="l('PhoneNumber')" name="phoneNumber">
                  <a-input :placeholder="l('PhoneNumber')" v-model:value="form.phoneNumber" />
                </a-form-item>
              </a-col>
            </a-row>
            <a-row>
              <a-col :span="12">
                <a-form-item :label="l('PasswordRepeat')" name="PasswordRepeat" :rules="passRepeat">
                  <a-input
                    :placeholder="l('Password')"
                    type="password"
                    v-model:value="form.PasswordRepeat"
                  />
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <!-- 下次登录需要修改密码 -->
                <a-form-item :label="l('ShouldChangePasswordOnNextLogin')">
                  <a-switch
                    v-model:checked="form.needToChangeThePassword"
                    :checkedChildren="l('Yes')"
                    :unCheckedChildren="l('No')"
                  />
                </a-form-item>
              </a-col>
            </a-row>

            <!-- 使用随机密码 -->
            <!-- <a-form-item :label="l('SetRandomPassword')">
              <a-switch
                v-model:checked="form.isSetRandomPassword"
                :checkedchildren="l('Yes')"
                :unCheckedChildren="l('No')"
                @change="setPwd"
              />
            </a-form-item> -->

            <!-- 密码核对 -->

            <!-- 发送激活邮件 -->
            <!-- <a-form-item :label="l('SendActivationEmail')">
                  <a-switch
                    v-model:checked="form.sendActivationEmail"
                    :checkedChildren="l('Yes')"
                    :unCheckedChildren="l('No')"
                  />
                </a-form-item> -->
            <a-row>
              <!-- 激活 -->
              <a-col :span="12">
                <a-form-item :label="l('Active')">
                  <a-switch
                    v-model:checked="form.isActive"
                    :checkedChildren="l('Yes')"
                    :unCheckedChildren="l('No')"
                  />
                </a-form-item>
              </a-col>

              <!-- 启用锁定 -->
              <a-col :span="12">
                <a-form-item :label="l('IsLockoutEnabled')">
                  <a-switch
                    v-model:checked="form.isLockoutEnabled"
                    :checkedChildren="l('Yes')"
                    :unCheckedChildren="l('No')"
                  />
                </a-form-item>
              </a-col>
            </a-row>
          </a-form>
        </a-tab-pane>
        <!-- 角色 -->
        <a-tab-pane key="2">
          <template #tab>
            <a-badge :count="checkedRoles.length">
              <medicine-box-outlined />
              {{ l('Roles') }}
            </a-badge>
          </template>
          <a-checkbox-group :options="roleList" v-model:value="checkedRoles" />
        </a-tab-pane>
        <!-- 组织单元 -->
        <a-tab-pane key="3">
          <template #tab>
            <share-alt-outlined />
            {{ l('OrganizationUnits') }}
          </template>
          <organization-unit-tree
            :multiple="true"
            :dropDownStyle="{ 'max-height': '500px' }"
            :data="organizationData"
            @selectedUnitChange="refreshGoFirstPage"
          ></organization-unit-tree>
        </a-tab-pane>
      </a-tabs>
    </div>
    <div class="modal-footer">
      <a-button :disabled="saving" @click="close()" type="button">
        <close-circle-outlined />
        {{ l('Cancel') }}
      </a-button>
      <a-button :loading="saving" :type="'primary'" @click="handleSubmit()">
        <save-outlined />
        {{ l('Save') }}
      </a-button>
      <a-button :loading="saving" :type="'primary'" @click="handleSubmit(false)">
        <save-outlined />
        {{ l('SaveDoesNotExit') }}
      </a-button>
    </div>
  </a-spin>
</template>

<script lang="ts">
  import { ModalComponentBase } from '/@/shared/component-base';
  import { AppConsts } from '/@/abpPro/AppConsts';
  import { ProfileServiceProxy, UserServiceProxy } from '/@/shared/service-proxies';
  import { OrganizationUnitTree } from '/@/app/admin-shared';
  import {
    PlusOutlined,
    MedicineBoxOutlined,
    ShareAltOutlined,
    UserOutlined,
    CloseCircleOutlined,
    SaveOutlined,
  } from '@ant-design/icons-vue';
  import { defineComponent } from 'vue';
  import {
    UserEditDto,
    CreateOrUpdateUserInput,
    UserRoleDto,
  } from '/@/shared/service-proxies/service-proxies';
  import { RuleObject } from 'ant-design-vue/lib/form/interface';
  function getBase64(file: Blob) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onload = () => resolve(reader.result);
      reader.onerror = (error) => reject(error);
    });
  }
  export default defineComponent({
    name: 'create-or-edit-user',
    components: {
      OrganizationUnitTree,
      PlusOutlined,
      MedicineBoxOutlined,
      ShareAltOutlined,
      UserOutlined,
      CloseCircleOutlined,
      SaveOutlined,
    },
    mixins: [ModalComponentBase],
    props: {
      // id: Number,
      userName: String,
      pageDataList: {
        type: Array,
        required: true,
      },
    },
    data() {
      const fileList: Array<any> = new Array<any>();
      const organizationList: any = null;
      const passwordRules: any = null;
      const passRepeat: any = null;
      return {
        id: null,
        formLayout: 'horizontal',
        form: {
          userName: '',
          password: '',
          emailAddress: '',
          phoneNumber: '',
          needToChangeThePassword: false,
          isActive: false,
          isLockoutEnabled: false,
          sendActivationEmail: false,
          isSetRandomPassword: true,
          PasswordRepeat: '',
          profilePictureId: '',
        },
        previewVisible: false,
        previewImage: '',
        // 上传图片
        fileList: fileList,
        uploadPictureUrl:
          AppConsts.remoteServiceBaseUrl +
          '/api/services/app/Profile/UploadProfilePictureReturnFileId',
        maxProfilPictureBytesValue: AppConsts.maxProfilPictureMb,
        uploadHeaders: {},
        profileServiceProxy: new ProfileServiceProxy(),
        userServiceProxy: new UserServiceProxy(),

        // 是否设置随机密码
        //isSetRandomPassword: true,
        // 角色list
        roleList: new Array<any>(),
        userRoleList: new Array<UserRoleDto>(),
        checkedRoles: [],
        // 选择组织单源数据
        organizationList: organizationList,
        selectedUnit: [] as any,
        activeKey: 1,
        rules: {
          // emailAddress: [
          //   { type: 'email', message: this.l('InvalidEmailAddress'), trigger: 'blur' },
          //   { required: true, message: this.l('ThisFieldIsRequired'), trigger: 'blur' },
          // ],
          userName: [
            {
              required: true,
              message: this.l('ThisFieldIsRequired'),
              trigger: 'blur',
            },
            { message: this.l('MaxLength', 32), max: 32 },
          ],
          // phoneNumber: [
          //   { required: true, message: this.l('ThisFieldIsRequired'), trigger: 'blur' },
          //   { message: this.l('MaxLength', 32), max: 24, trigger: 'blur' },
          // ],
        },
        organizationData: new Array<any>(),
        defaultOrganization: new Array<any>(),
        passwordRules: passwordRules,
        passRepeat: passRepeat,
      };
    },
    mounted() {
      this.getPageData(this.pageDataList[0]);
    },
    methods: {
      initData() {
        this.fullData(); // 模态框必须,填充数据到data字段
        Object.assign(this.uploadHeaders, {
          Authorization: 'Bearer ' + abp.auth.getToken(),
        });
        if (this.id) {
          this.passwordRules = [
            { validator: this.isEdit, trigger: 'blur' },
            { validator: this.notEdit, trigger: 'blur' },
          ];
          this.passRepeat = [{ validator: this.compareToFirstPasswordNew, trigger: 'blur' }];
        } else {
          this.passwordRules = [
            {
              required: true,
              message: this.l('ThisFieldIsRequired'),
              trigger: 'blur',
            },
            { validator: this.notEdit, trigger: 'blur' },
          ];
          this.passRepeat = [
            {
              required: true,
              message: this.l('ThisFieldIsRequired'),
              trigger: 'blur',
            },
            { validator: this.compareWithoutid, trigger: 'blur' },
          ];
        }
        this.init();
      },
      getPageData(id) {
        this.id = id;
        this.fileList = [];
        this.previewImage = '';
        this.initData();
      },
      handleClose() {
        //关闭后清空页面数据
        (this.$refs.formRef as any).resetFields();
        this.fileList = [];
        this.previewImage = '';
      },
      /**
       * 初始化
       */
      init() {
        this.form.isSetRandomPassword = false;
        this.loading = true;
        this.userServiceProxy
          .getForEditTree(this.id)
          .finally(() => (this.loading = false))
          .then((result: any) => {
            this.defaultOrganization = result.memberedOrganizationUnits;
            this.userRoleList = result.roles as Array<UserRoleDto>;
            this.roleList = result.roles?.map((item) => {
              if (this.id) {
                return {
                  label: item.roleDisplayName,
                  value: item.roleDisplayName,
                  disabled: item.inheritedFromOrganizationUnit as boolean,
                };
              }
              return {
                label: item.roleDisplayName,
                value: item.roleDisplayName,
              };
            }) as Array<any>;
            this.checkedRoles = result.roles
              ?.filter((item) => item.isAssigned)
              .map((item) => {
                return item.roleDisplayName;
              });
            this.organizationList = result.allOrganizationUnits;
            this.organizationData = result;
            // 设置表单
            this.$nextTick(() => {
              this.form.userName = result.user.userName;
              this.form.emailAddress = result.user.emailAddress as string;
              this.form.phoneNumber = result.user.phoneNumber as string;
              if (this.id) this.form.isSetRandomPassword = false;
              this.form.password = result.user.password as string;
              // this.form.sendActivationEmail = result.user.sendActivationEmail as boolean;
              this.form.isActive = result.user.isActive;
              this.form.isLockoutEnabled = result.user.isLockoutEnabled;
              this.form.PasswordRepeat = result.user.password as string;
              this.form.profilePictureId = result.user.profilePictureId;
            });
            // 设置头像
            if (result.user.profilePictureId) {
              this.getProfilePicture(result.user.profilePictureId);
            }
          });
      },
      /**
       * 验证密码输入
       */
      compareToFirstPassword(
        _rule: any,
        value: any,
        callback: (arg0?: string | undefined) => void,
      ) {
        if (value && value !== (this.$refs.formRef as any).getFieldValue('password')) {
          callback(this.l('PasswordsDontMatch'));
        } else {
          callback();
        }
      },
      compareToFirstPasswordNew(_rule: RuleObject, value: string) {
        console.log(!this.form.password, !value);
        if (this.form.password && value) {
          if (value.includes(' ')) {
            return Promise.reject('不能输入空格');
          }
          if (this.form.password.trim() !== value.trim()) {
            return Promise.reject(this.l('TwoInputsDonotMatch'));
          }
        }
        if (this.form.password && (value === null || value === '')) {
          return Promise.reject(this.l('TwoInputsDonotMatch'));
        }
        if (this.id) {
          return Promise.resolve();
        }
        return Promise.resolve();
      },
      compareWithoutid(_rule: RuleObject, value: string) {
        if (value !== this.form.password) {
          return Promise.reject(this.l('TwoInputsDonotMatch'));
        }
        return Promise.resolve();
      },
      setPwd() {
        this.form.sendActivationEmail === true
          ? this.form.isSetRandomPassword === false
          : this.form.isSetRandomPassword === true;
      },
      /**
       * 提交表单
       */
      handleSubmit(closeFlag = true) {
        (this.$refs.formRef as any).validate().then(() => {
          let _user: UserEditDto = new UserEditDto();
          _user.init(this.form);
          if (this.id !== null || this.id !== undefined) _user.id = this.id;
          let _createorupdateuserinput: CreateOrUpdateUserInput = new CreateOrUpdateUserInput();
          let parmas = {
            assignedRoleNames: [],
            organizationUnits: [],
            user: _user,
            sendActivationEmail: this.form.sendActivationEmail,
            setRandomPassword: this.form.isSetRandomPassword,
          };
          //过滤组织单元
          if (this.selectedUnit.length < 1 && this.id) {
            this.defaultOrganization.map((item) => {
              let id = this.organizationList.find((i) => i.code === item).id;
              if (id) {
                parmas.organizationUnits.push(id as never);
              }
            });
          } else {
            parmas.organizationUnits = this.selectedUnit?.checked;
          }
          if (this.fileList.length > 0) {
            parmas.user.profilePictureId =
              this.form.profilePictureId == null
                ? this.fileList[this.fileList.length - 1].response.result.profilePictureId
                : this.form.profilePictureId;
          } else {
            parmas.user.profilePictureId = undefined;
          }
          parmas.user.needToChangeThePassword = this.form.needToChangeThePassword as boolean;
          // 处理角色
          if (this.checkedRoles.length > 0) {
          }
          this.checkedRoles.map((item) => {
            if (this.id) {
              let temporary = this.userRoleList.find(
                (i) => i.roleDisplayName == item && !i.inheritedFromOrganizationUnit,
              )?.roleName;
              if (temporary) {
                parmas.assignedRoleNames.push(temporary as never);
              }
            } else {
              let temporary = this.userRoleList.find((i) => i.roleDisplayName == item)?.roleName;
              if (temporary) {
                parmas.assignedRoleNames.push(temporary as never);
              }
            }
          });

          _createorupdateuserinput.init(parmas);
          this.loading = true;
          this.userServiceProxy
            .createOrUpdate(_createorupdateuserinput)
            .finally(() => {
              this.loading = false;
            })
            .then(() => {
              /**
               * 当前账号
               * 更新用户头像
               * 使用this.fileList最后一个
               * 默认头像
               */
              if (this.id === this.abpSession.userId) {
                abp.event.trigger(
                  'userAvatarChange',
                  this.fileList.length > 0
                    ? this.fileList[this.fileList.length - 1].url
                    : '/assets/images/user.png',
                );
              }
              this.notify.success(this.l('SavedSuccessfully'));
              this.loading = false;
              if (closeFlag) {
                this.success();
              } else {
                this.saveNotClose();
              }
            });
        });
      },
      /**
       * 上传图片
       */
      beforeUpload(file: any) {
        const isJPG =
          file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif';
        if (!isJPG) {
          abp.message.error(this.l('OnlySupportPictureFile'));
        }
        const isLtXM = file.size / 1024 / 1024 < this.maxProfilPictureBytesValue;
        if (!isLtXM) {
          abp.message.error(
            this.l('ProfilePicture_Warn_SizeLimit', this.maxProfilPictureBytesValue),
          );
        }
        const isValid = isJPG && isLtXM;
        return isValid;
      },
      handleCancel() {
        this.previewVisible = false;
      },
      async handlePreview(file: any) {
        if (!file.url && !file.preview) {
          file.preview = await getBase64(file.originFileObj);
        }
        this.previewImage = file.url || file.preview;
        this.previewVisible = true;
      },
      uploadPictureChange(item: any) {
        //await this.handlePreview(item.file)
        if (item.file.status === 'done') {
          this.fileList = item.fileList;
          if (this.fileList.length > 0) {
            this.form.profilePictureId =
              this.fileList[this.fileList.length - 1].response.result.profilePictureId;
          } else {
            this.form.profilePictureId = '';
          }
          this.previewImage = '';
          if (this.form.profilePictureId) {
            this.getProfilePicture(this.form.profilePictureId);
          }
          this.notify.success(this.l('FileSavedSuccessfully'));
          return;
        }
        if (item.file.status === 'error') {
          this.notify.error(this.l('FileSavedFailed'));
          return;
        }
      },
      /**
       * 通过头像Id获取头像
       * @param profilePictureId 头像Id
       */
      getProfilePicture(profilePictureId: string | undefined) {
        if (profilePictureId) {
          this.loading = true;
          this.fileList = [];
          this.previewImage = '';
          this.profileServiceProxy
            .getProfilePictureById(profilePictureId)
            .finally(() => (this.loading = false))
            .then((result) => {
              if (result && result.profilePicture) {
                let profilePreviewImage = 'data:image/jpeg;base64,' + result.profilePicture;
                this.previewImage = profilePreviewImage;
                // 把图像加到头像列表 显示
                this.fileList.push({
                  uid: -1,
                  name: profilePictureId,
                  status: 'done',
                  url: profilePreviewImage,
                  thumbUrl: profilePreviewImage,
                });
              }
            });
        }
      },
      /**
       * 选择完权限过滤
       */
      refreshGoFirstPage(data: never[]) {
        this.selectedUnit = data;
      },
      isEdit(_rule: RuleObject, value: string) {
        if (this.id) {
          return Promise.resolve();
        }
        if (value === null) {
          return Promise.reject(this.l('ThisFieldIsRequired'));
        }
        return Promise.resolve();
      },
      notEdit(_rule: RuleObject, value: string) {
        if (this.id && !value) {
          return Promise.resolve();
        } else {
          if (value === null || value === '') {
            return Promise.reject();
          }
          if (value.includes(' ')) {
            return Promise.reject('不能输入空格');
          }
          if (
            value.length <
            abp.setting.getInt('Abp.Zero.UserManagement.PasswordComplexity.RequiredLength')
          ) {
            return Promise.reject(
              this.l(
                'MinLength',
                abp.setting.get('Abp.Zero.UserManagement.PasswordComplexity.RequiredLength'),
              ),
            );
          }
          if (value.length > 32) {
            return Promise.reject(this.l('MaxLength', 32));
          }
          return Promise.resolve();
        }
      },
    },
  });
</script>

<style scoped lang="less">
  .anticon-user {
    margin-right: 10px;
  }

  .ant-upload-select-picture-card i {
    font-size: 32px;
    color: #999;
  }

  .ant-upload-select-picture-card .ant-upload-text {
    margin-top: 8px;
    color: #666;
  }

  .halfwidth {
    :deep(.ant-form-item-label) {
      width: 30%;
    }
  }

  .next-password {
    :deep(.ant-form-item-label) {
      width: 45%;
    }
  }
  .ant-col-12 {
    padding: 0 20px;
  }
</style>
